class Router {
public:
    Router(int memoryLimit) {
        _limit = memoryLimit;
    }

    bool addPacket(int source, int destination, int timestamp) {
        tuple<int, int, int> p = make_tuple(source, destination, timestamp);
        if (_is_exist.find(p) != _is_exist.end()) return false;

        if (_limit == _length) forwardPacket();

        _length++;
        _q.push_back(p);
        _is_exist.insert(p);
        _table[destination].push_back(timestamp);
        return true;
    }

    vector<int> forwardPacket() {
        vector<int> ret;
        if (_q.empty()) return ret;

        tuple<int, int, int> a = _q.front();
        _q.pop_front();
        _is_exist.erase(a);
        ret = vector<int>{ get<0>(a), get<1>(a), get<2>(a) };
        _table[ret[1]].pop_front();
        _length--;

        return ret;
    }

    int getCount(int destination, int startTime, int endTime) {
        auto it1 = lower_bound(_table[destination].begin(), _table[destination].end(), startTime);
        auto it2 = upper_bound(_table[destination].begin(), _table[destination].end(), endTime);

        return it2 - it1;
    }
private:
    int _limit;
    int _length = 0;
    set<tuple<int, int, int>> _is_exist;
    unordered_map<int, deque<int>> _table;
    deque<tuple<int, int, int>> _q;
};

/**
 * Your Router object will be instantiated and called as such:
 * Router* obj = new Router(memoryLimit);
 * bool param_1 = obj->addPacket(source,destination,timestamp);
 * vector<int> param_2 = obj->forwardPacket();
 * int param_3 = obj->getCount(destination,startTime,endTime);
 */